import {message,} from 'ant-design-vue'
import Axios from "axios"
import * as utils from './utils'
import {getStore} from './storage'
import $store from '../../store/index';
import $router from '../../router/index';
import {notice} from './notice';
import config from "../../config/config";

let HOME_PAGE = config.HOME_PAGE;
const currentOrganization = getStore('currentOrganization', true);
if (currentOrganization) {
    HOME_PAGE = HOME_PAGE + '/' + currentOrganization.code;
}
const crossDomain = config.crossDomain;
let axiosConfig = {};
if (crossDomain) {
    axiosConfig.withCredentials = true;
    axiosConfig.crossDomain = true;
}
const $http = Axios.create(axiosConfig);

// Before request
$http.interceptors.request.use(
    config => {
        //正在请求更新token时，其他接口等待
        if (window.urls && window.urls.indexOf(config.url) >= 0) {
            config.url2 = config.url
            config.data2 = config.data || {}
        }
        config.url = utils.getApiUrl(config.url);
        if (config.url2 && !config.is_check_data_diff) {
            config.url = getApiUrl2(config.url2);
        } else if (!config.is_check_data_diff) {
            console.warn('old call:', config.url, config)
        }
        if (config.method === 'post') {
            const querystring = require('querystring');
            config.data = querystring.stringify(config.data);
        }
        let tokenList = getStore('tokenList', true);
        if (tokenList) {
            let accessToken = tokenList.accessToken;
            let tokenType = tokenList.tokenType;
            config.headers.Authorization = `${tokenType} ${accessToken}`;
        }
        let organization = getStore('currentOrganization', true);
        if (organization) {
            config.headers.organizationCode = organization.code;
        }
        return config;
    },
    error => {
        return Promise.reject(error);
    }
);
// After request
$http.interceptors.response.use(
    response => {
        let is_check_data_diff = false
        let response_ori = response
        if (response.config.url2
                && !response.config.is_check_data_diff
                && window.urls_update.indexOf(response.config.url2) < 0) {
            let url2 = response.config.url2
            is_check_data_diff = true;

            //这里调用diff的目的是为了先进行一次排序
            //排序的目的是为了避免获取php接口后再排序会导致前端逻辑异常
            diff(response_ori.data, response_ori.data, response_ori.data, response_ori.data, {response:response_ori});

            try {
                $http.post(url2, response.config.data2, {is_check_data_diff:true})
                .then ( data => {
                    if (diff(data, response_ori.data, data, response_ori.data, {response:response_ori})) {
                        console.error('diff url:', url2, data, response_ori.data)
                    }
                })
            }catch(ex) {
                console.error('ex', ex)
            }
        }
        response = response.data;
        response.code = Number(response.code);
        switch (response.code) {
            case 200:
                response.msg !== '' && notice(response.msg, 'message', 'success');
                return Promise.resolve(response);
            case 401:
                $router.replace('/member/login?redirect=' + $router.currentRoute.fullPath);
                $store.dispatch('SET_LOGOUT');
                return Promise.resolve(response);
            case 403:
                notice({
                    title: response.msg !== '' ? response.msg : '无权限操作资源，访问被拒绝',
                }, 'notice', 'error', 5);
                return Promise.resolve(response);
            case 4031:
                //无权限操作资源
                notice({
                    title: response.msg !== '' ? response.msg : '无权限操作资源，访问被拒绝',
                }, 'notice', 'error', 5);
                $router.replace(HOME_PAGE);
                return Promise.resolve(response);
            case 4041:
                //资源不存在
                notice({
                    title: response.msg !== '' ? response.msg : '资源不存在',
                }, 'notice', 'warning', 5);
                $router.replace(HOME_PAGE);
                return Promise.resolve(response);
        }
        if (response.code === 200) {
            notice({
                title: '请求错误 ' + response.code,
                desc: response.msg
            }, 'notice', 'warning', 5);
            return Promise.resolve(response);
        } else {
            response.msg !== '' && notice({
                title: response.msg,
            }, 'notice', 'error', 5);
            return Promise.resolve(response);
        }
        /*if (response.code == 200) {
            response.msg !== '' && notice(response.msg, 'message', 'success');
            return Promise.resolve(response);
        } else if (response.code === 401) {
            // notice('登录超时，请重新登录');
            $router.replace('/member/login?redirect=' + $router.currentRoute.fullPath);
            $store.dispatch('SET_LOGOUT');
            return new Promise(() => {});
        } else if (response.code === 4010) {
            refreshAccessToken(refreshToken).then(res=>{
                console.log(res);
                return new Promise(() => {
                });
            });
        }else if (response.code === 403) {
            // $router.replace('/403');
            //无权限操作资源
            notice({
                title: response.msg !== '' ? response.msg : '无权限操作资源，访问被拒绝',
            }, 'notice', 'error', 5);
            return Promise.reject(response.msg);
            // return new Promise(() => {});
        } else if (response.code === 4031) {
            // $router.replace('/403');
            //无权限操作资源
            notice({
                title: response.msg !== '' ? response.msg : '无权限操作资源，访问被拒绝',
            }, 'notice', 'error', 5);
            $router.replace(HOME_PAGE);
            return Promise.reject(response.msg);
        } else if (response.code <= 400) {
            response.msg !== '' && notice({
                title: response.msg,
            }, 'notice', 'error', 5);
            return Promise.resolve(response);
        } else if (response.code == 404) {
            //资源不存在
            notice({
                title: response.msg !== '' ? response.msg : '资源不存在',
            }, 'notice', 'warning', 5);
            $router.replace(HOME_PAGE);
            return new Promise(() => {
            });
        } else if (response.code < 500) {
            notice({
                title: '请求错误 ' + response.code,
                desc: response.msg
            }, 'notice', 'warning', 5);
            // $router.back();
            return Promise.reject(response);
        } else {
            notice({
                title: '请求错误 ' + response.code,
                desc: '路径：' + self.url + '，' +
                    response.msg || '未知错误，请联系管理员或稍后重试' +
                    '。'
            }, 'notice', 'warning', 5);
            return new Promise(() => {
            });
        }*/
    },
    error => {
        const response = error.response.data;
        console.log(response);
        response.code = Number(response.code);
        message.destroy();
        switch (response.code) {
            default:
                response.msg !== '' && notice({
                    title: response.msg,
                }, 'notice', 'error', 5);
                return Promise.reject(error);
        }
    }
);

let sort = function(list) {
    try {
        return list.sort(function (a, b) {
            let aValue = a.show_slider ? 'a' : 'b';
            let bValue = b.show_slider ? 'a' : 'b';
            if (aValue != bValue) {
                return aValue.localeCompare(bValue)
            }
            aValue = aValue + (parseInt(a.sort ? a.sort : 0) + 10000000)
            bValue = bValue + (parseInt(b.sort ? b.sort : 0) + 10000000)
            if (aValue != bValue) {
                return aValue.localeCompare(bValue)
            }
            aValue = aValue + (a.name || '') + ','
            bValue = bValue + (b.name || '') + ','
            if (aValue != bValue) {
                return aValue.localeCompare(bValue)
            }
            aValue = aValue + (a.code || '') + ','
            bValue = bValue + (b.code || '') + ','
            if (aValue != bValue) {
                return aValue.localeCompare(bValue)
            }
            aValue = aValue + (a.title || '') + ','
            bValue = bValue + (b.title || '') + ','
            if (aValue != bValue) {
                return aValue.localeCompare(bValue)
            }
            aValue = aValue + (a.id || '') + ','
            bValue = bValue + (b.id || '') + ','
            if (aValue != bValue) {
                return aValue.localeCompare(bValue)
            }
            return (a+'').localeCompare(b+'')
        });
    }catch (ex) {
        console.error('ex', ex)
        console.error('list', list)
        return list
    }
}

var diff = function(item, item2, data, data2, params) {
    if (!('miss_null_prop' in params)) params.miss_null_prop = {}
    if (!('miss_prop' in params)) params.miss_prop = {}
    if (!('diff_prop' in params)) params.diff_prop = {}
        
    const { miss_null_prop, miss_prop, diff_prop, response } = params

    if (item !== null && item2 !== null && item instanceof Array && item2 instanceof Array) {
        if (item.length != item2.length) {
            console.error('data length diff:', item, item2, data, data2);
            return true;
        }
        let isDiff = false
        for(let i = 0; i < item.length; i++) {
            let _item = item[i]
            let _item2 = item2[i]
            if (diff(_item, _item2, data, data2, params)) {
                console.error('is diff, i:',i,',item:', _item, ',item2:', _item2, ',', item, ',', item2, ',data:', data, ',data2:', data2)
                isDiff = true;
            }
        }
        if (isDiff) {
            return true
        }
        // console.log('same array,length:', item.length, ',item:', item, ',item2:', item2, ',', data, ',', data2)
        return false
    }
    let i_item, i_item2, d_item, d_item2
    try {i_item = parseInt(item)}catch(ex) {}
    try {i_item2 = parseInt(item2)}catch(ex) {}
    try {d_item = parseFloat(item)}catch(ex) {}
    try {d_item2 = parseFloat(item2)}catch(ex) {}
    if (item !== null && item2 !== null
            && item !== undefined && item2 !== undefined
            && item !== true && item2 !== true
            && item2 !== false && item2 !== false
            && item !== item+'' && item2 !== item2+''
            && item !== i_item && item2 !== i_item2
            && item !== d_item && item2 !== d_item2
            && item instanceof Object && item2 instanceof Object) {
        let isDiff = false
        for(let p in item) {
            if (p == 'description'
                    || p == 'deleted_time'
                    || p == 'schedule'
                    || p == 'access_control_type'
                    || p == 'order'
                    || p == 'template_code'
                    || p == 'organization_code'
                    || p == 'prefix'
                    || p == 'open_prefix'
                    || p == 'archive'
                    || p == 'archive_time'
                    || p == 'open_begin_time'
                    || p == 'open_task_private'
                    || p == 'task_board_theme'
                    || p == 'private'
                    || p == 'cover'
                    || p == 'auto_update_schedule'
            ) {
                //这个接口的这些属性是project的属性
                if (response.config.url.indexOf('project/task/selfList') >= 0) {
                    continue;
                }
            }

            if (!(p in item2)) {
                if (item[p] === null) {
                    if (!(p in miss_null_prop)) {
                        miss_null_prop[p] = p
                        // console.log('miss prop(old is null),p:', p, ',item:', item, ',item2:', item2, ',', data, data2);
                    }
                    continue;
                }
                if (!(p in miss_prop)) {
                    miss_prop[p] = p
                    isDiff = true
                    console.error('miss prop,p:', p, item[p], ',item:', item, ',item2:', item2, ',', data, data2);
                }
                continue
            }
            try {i_item = parseInt(item[p])}catch(ex) {}
            try {i_item2 = parseInt(item2[p])}catch(ex) {}
            try {d_item = parseFloat(item[p])}catch(ex) {}
            try {d_item2 = parseFloat(item2[p])}catch(ex) {}
            
            let needSort = true;
            for(let url_without_sort in window.urls_without_sort) {
                url_without_sort = window.urls_without_sort[url_without_sort]
                if (response.config.url.indexOf(url_without_sort) >= 0) {
                    needSort = false;
                    break;
                }
            }
            if (needSort) {
                //接口排序一致，或php接口中没有用于排序的字段
                if (item[p] && item[p] instanceof Array && item[p].length) {
                    item[p] = sort(item[p])
                }
                if (item2[p] && item2[p] instanceof Array && item2[p].length) {
                    item2[p] = sort(item2[p])
                }
            }

            //======================
            //以下处理为忽略一些不应该由后端返回的属性。因为接口返回后，会被前端处理，在比较时可能已经被前端改变
            //需要注意的是，这些属性应该由前端创建、使用，不应该由后端返回。
            //由后端返回相当于后端控制了前端的一些展示逻辑，在非必要的情况下尽量做到UI与接口分离
            if (p == 'tasks' || p == 'unDoneTasks' || p == 'doneTasks') {
                if (response.config.url.indexOf('project/task_stages') >= 0) {
                    continue;
                }
            }
            if (p == 'tasksLoading') {
                if (response.config.url.indexOf('project/task_stages') >= 0) {
                    continue;
                }
            }

            //======================
            //page 应为数值类型，但是在以下几个接口中php接口返回的类型为字符串
            if (p == 'page' && item[p] == item2[p]) {
                if (response.config.url.indexOf('project/task_stages') >= 0
                        || response.config.url.indexOf('project/project_member/index') >= 0
                        || response.config.url.indexOf('project/department') >= 0
                        || response.config.url.indexOf('project/account') >= 0
                ) {
                    continue;
                }
                console.log('response for page', response)
                continue
            }

            //======================
            //在第一次登录后调用的project/index接口中php接口返回的show_slider类型为数值，
            //但是php接口在系统设置-系统管理-菜单路由的project/menu/menu接口中为bool
            if (p == 'show_slider' && item[p] == item2[p]) {
                if (response.config.url.indexOf('project/menu/menu') >= 0) {
                    continue;
                }
            }

            //比较数组类型
            if (item[p] && item2[p] && item[p] instanceof Array && item2[p] instanceof Array && 'length' in item[p] && 'length' in item2[p]) {
                if (diff(item[p], item2[p], data, data2, params)) {
                    console.error('data length diff for prop:', p, item[p].length, item2[p].length);
                    isDiff = true;
                }
                continue
            }

            if (item[p] !== null && item2[p] !== null
                    && item[p] !== undefined && item2[p] !== undefined
                    && item[p] !== true && item2[p] !== true
                    && item[p] !== false && item2[p] !== false
                    && item[p] !== item[p]+'' && item2[p] !== item2[p]+''
                    && item[p] !== i_item && item2[p] !== i_item2
                    && item[p] !== d_item && item2[p] !== d_item2
                    && item[p] instanceof Object && item2[p] instanceof Object) {
                if (diff(item[p], item2[p], data, data2, params)) {
                    isDiff = true;
                }
                continue
            }
            if (item[p] === null && item2[p] === undefined) {
                if (!(p in miss_null_prop)) {
                    miss_null_prop[p] = p
                    // console.error('miss prop(old is null),p:',p,',item:', item[p], ',item2:', item2[p], ',', item, item2, data, data2)
                }
            } else if (item[p] !== item2[p]) {
                if (!(p in diff_prop)) {
                    diff_prop[p] = p
                    console.error('data diff,p:',p,',item:', item[p], ',item2:', item2[p], ',', item, item2, data, data2)
                }
                isDiff = true
            }
        }
        if (isDiff) {
            return true
        }
        // console.log('same obj,:', ',item:', item, ',item2:', item2, ',data:', data, ',data2:', data2)
    } else if (item === null && item2 === undefined) {
        console.log('miss prop(old is null):', ',item:', item, ',item2:', item2, ',', data, data2);
    } else if (item !== item2) {
        console.error('data diff,',',item:', item, ',item2:', item2, ',', data, data2)
        return true
    }
    return false
}

const getApiUrl2 = (api) => {
    if (
        process.env.VUE_APP_CROSS_DOMAIN === 'true'
        || process.env.VUE_APP_CROSS_DOMAIN === true
        || process.env.VUE_APP_CROSS_DOMAIN === ''
        || process.env.VUE_APP_CROSS_DOMAIN === null) {
        return process.env.VUE_APP_API_URL + '2/' + api; //开启跨域直接返回
    }
    if (process.env.NODE_ENV === 'production') {
        return process.env.VUE_APP_API_URL + '2/' + api;
    } else {
        return '/api2/' + api;
    }
};

export default $http;
